package com.qidian.buy.search.service.impl;

import com.qidian.buy.entity.Item;
import com.qidian.buy.search.service.SearchService;
import com.qidian.buy.util.pojo.BuyResult;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Author: 戴着假发的程序员
 * Date: 2023-07-11 11:37
 * company: 起点编程
 * Description:
 **/
@Service
public class SearchServiceImpl implements SearchService {
    @Autowired
    private RestTemplate restTemplate; // 远程调用工具对象
    @Autowired
    private RestHighLevelClient client;// 链接ES的客户端
    @Override
    public BuyResult importIndex() {
        // 准备一个默认的页码
        int pageNum = 1;
        int maxPageNum = 1;
        for (;pageNum <= maxPageNum;pageNum++) {
            // 进行远程调用
            BuyResult result = restTemplate.getForObject("http://buy-product/buy/item/list?limit=50&page=" + pageNum, BuyResult.class);
            // 获取数据  (BuyResult中的data返回的是一个LinkedHashMap)
            LinkedHashMap map = (LinkedHashMap) result.getData();
            if(pageNum == 1) {
                // 获取最大页码
                maxPageNum = new Integer(map.get("pages").toString());
            }
            // 获取商品列表
            List<LinkedHashMap> items = (List<LinkedHashMap>) map.get("records");
            // 遍历商品列表，将商品信息存入索引库
            for (LinkedHashMap item : items) {
                // 将商品信息放入索引库
                IndexRequest request = new IndexRequest("item");
                // 设置id为商品的id
                request.id(item.get("id").toString());
                // 删除不需要的属性值
                item.remove("created");
                item.remove("updated");
                item.remove("num");
                item.remove("itemDesc");
                item.remove("status");
                item.remove("barcode");
                // 设置数据
                request.source(item);
                // 提交到索引库
                try {
                    IndexResponse response = client.index(request, RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return BuyResult.ok();
    }

    @Override
    public BuyResult search(int page, int limit, String kw) {
        Map result = new HashMap<>();
        result.put("limit",limit);
        result.put("page",page);

        // 计算查询的开始位置
        int start = (page - 1) * limit;
        // 开始查询
        // 组织查询条件
        SearchRequest request = new SearchRequest("item");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        if(kw != null && !"".equals(kw)) {
            sourceBuilder.query(QueryBuilders.matchQuery("title", kw));
        }
        // 配置分页
        sourceBuilder.from(start);
        sourceBuilder.size(limit);
        // 高亮现实配置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("title");
        sourceBuilder.highlighter(highlightBuilder);
        request.source(sourceBuilder);
        // 开始查询
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 获取信息
            long total = response.getHits().getTotalHits().value;
            result.put("total",total);
            // 计算最大页码
            int pages = (int)Math.ceil(total * 1.0 / limit);
            result.put("pages",pages);
            // 获取查询的数据列表
            SearchHits hits = response.getHits();
            List<Map> items = new ArrayList<>();
            for (SearchHit hit : hits){
                Map<String, Object> map = hit.getSourceAsMap();
                // 取出高亮现实的标题
                HighlightField titleField = hit.getHighlightFields().get("title");
                if(titleField != null) {
                    Text[] fragments = titleField.getFragments();
                    if (fragments != null && fragments.length > 0) {
                        String title = fragments[0].toString();
                        map.put("title", title);
                    }
                }
                items.add(map);
            }
            result.put("data",items);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return BuyResult.ok(result);
    }
}
